#include <openssl/des.h>
#include <cstring>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include "fy_crypt.h"

void DES_encrypt(uchar *input_buf, uchar *output_buf, uchar *key)
{
    DES_cblock DES_key;
    DES_key_schedule schedule;
    memcpy(&DES_key, key, 8);
    DES_set_key_unchecked(&DES_key, &schedule);
    DES_cblock input;
    DES_cblock output;
    memcpy(&input, input_buf, 8);
    DES_ecb_encrypt(&input, &output, &schedule, DES_ENCRYPT);
    memcpy(output_buf, &output, 8);
}

void DES_decrypt(uchar *input_buf, uchar *output_buf, uchar *key)
{
    DES_cblock DES_key;
    DES_key_schedule schedule;
    memcpy(&DES_key, key, 8);
    DES_set_key_unchecked(&DES_key, &schedule);
    DES_cblock input;
    DES_cblock output;
    memcpy(&input, input_buf, 8);
    DES_ecb_encrypt(&input, &output, &schedule, DES_DECRYPT);
    memcpy(output_buf, &output, 8);
}

int padding = RSA_PKCS1_PADDING;

RSA *create_RSA(uchar *key, int flag)
{
    RSA *rsa = nullptr;
    BIO *key_BIO;
    key_BIO = BIO_new_mem_buf(key, -1);
    if (flag)
        rsa = PEM_read_bio_RSA_PUBKEY(key_BIO, &rsa, NULL, NULL);
    else
        rsa = PEM_read_bio_RSAPrivateKey(key_BIO, &rsa, NULL, NULL);
    return rsa;
}

int RSA_public_encrypt(uchar *input_buf, int input_buf_len, uchar *output_buf, uchar *public_key)
{
    RSA *rsa = create_RSA(public_key, 1);
    int len = RSA_public_encrypt(input_buf_len, input_buf, output_buf, rsa, padding);
    return len;
}

int RSA_private_decrypt(uchar *enc_data, int input_buf_len, uchar *output_buf, uchar *private_key)
{
    RSA *rsa = create_RSA(private_key, 0);
    int len = RSA_private_decrypt(input_buf_len, enc_data, output_buf, rsa, padding);
    return len;
}

int RSA_private_encrypt(uchar *input_buf, int input_buf_len, uchar *output_buf, uchar *private_key)
{
    RSA *rsa = create_RSA(private_key, 0);
    int len = RSA_private_encrypt(input_buf_len, input_buf, output_buf, rsa, padding);
    return len;
}

int RSA_public_decrypt(uchar *enc_data, int input_buf_len, uchar *output_buf, uchar *public_key)
{
    RSA *rsa = create_RSA(public_key, 1);
    int len = RSA_public_decrypt(input_buf_len, enc_data, output_buf, rsa, padding);
    return len;
}
